package itheima01;

import utils.C3P0Util;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

/*
    JDBC完成转账功能(加入事务管理)
    场景: tom 欠 jerry 1000元  使用2条update语句
        1.tom-1000
        2.jerry+1000

    以上2条sql应该看成一组(一个整体),必须使用一个事务,必须保证使用同一个Connection对象
        以上2条sql要么全部都执行,要么全部都不执行

    事务管理的流程:
        1.开启事务
        2.执行sql语句,多条sql语句正常执行,没有出现问题,提交事务,把数据持久化到数据库
        3.执行sql语句,多条sql语句执行过程中出现问题,回滚事务,把数据回退到开启事务之前的状态
        4.关闭资源

    与事务相关的方法,都定义在java.sql.Connection接口中:
        public void setAutoCommit(boolean flag): 将此连接的自动提交模式设置为给定状态flag。
            参数:
                boolean flag:
                    - 为 true 表示启用自动提交模式
                    - 为 false 表示禁用自动提交模式,手动提交,开启事务

        public void commit(): 提交事务,把数据持久化到数据库

        void rollback(): 取消在当前事务中进行的所有更改,回滚事务,把数据回退到开启事务之前的状态

    代码格式:
        try{
            1.获取连接Connection对象
            2.开启事务
            con.setAutoCommit()
            3.Connection对象获取执行sql语句的Statement对象
            4.定义2条sql语句(2条update语句:扣款,收款)
            5.Statement对象执行sql语句,获取结果
            6.如果sql语句正常执行,没有出现问题,提交事务
            con.commit;
            7.处理结果
        } catch(Exception e){
            8.如果sql语句执行过程中出现问题,回滚事务
            con.rollback;
        } finally{
            9.关闭资源
        }

    步骤:
        1.获取连接Connection对象
        2.Connection对象开启事务
        3.Connection对象获取执行sql语句的Statement对象
        4.定义2条sql语句(2条update语句:扣款,收款)
        5.Statement对象执行sql语句,获取结果
        6.如果sql语句正常执行,没有出现问题,提交事务
        7.处理结果
        8.如果sql语句执行过程中出现问题,回滚事务
        9.关闭资源
 */
public class Demo02Account {
    public static void main(String[] args) {
        //提示变量的作用域
        Connection con = null;
        Statement stmt = null;
        try {
            //1.获取连接Connection对象
            con = C3P0Util.getConnection();

            //2.Connection对象开启事务
            con.setAutoCommit(false);

            //3.Connection对象获取执行sql语句的Statement对象
            stmt = con.createStatement();

            //4.定义2条sql语句(2条update语句:扣款,收款)
            String tomSql = "update account set money=money-1000 where name='tom'";
            String jerrySql = "update account set money=money+1000 where name='jerry'";

            //5.Statement对象执行sql语句,获取结果
            int tomResult = stmt.executeUpdate(tomSql);

            System.out.println(1/0);//出了异常

            int jerryResult = stmt.executeUpdate(jerrySql);


            //7.处理结果
            if(tomResult>0) {
                System.out.println("tom账户成功扣款1000元~~~");
            } else {
                System.out.println("tom账户扣款1000元失败~~~");
            }

            if(jerryResult>0) {
                System.out.println("jerry账户收款1000元成功~~~");
            } else {
                System.out.println("jerry账户收款1000元失败~~~");
            }

            //6.如果sql语句正常执行,没有出现问题,提交事务
            con.commit();



        } catch (Exception e) {
            e.printStackTrace();
            //8.如果sql语句执行过程中出现问题,回滚事务
            if(con!=null) {
                try {
                    con.rollback();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }
        } finally {
            //9.关闭资源
            C3P0Util.release(con,stmt,null);
        }
    }
}
